#ifndef SM_YATI_CALLBACKS_H
#define SM_YATI_CALLBACKS_H

#include "lock.h"
#include "sm_api.h"

#include "BaseApplication.h"

#include <Ogre.h>

using namespace sm::faceapi::samplecode;

namespace ogre_sm
{
	Mutex g_mutex;
	BaseApplication* g_app;

	unsigned short g_overlay_flags(SM_API_VIDEO_DISPLAY_HEAD_MESH);

	void STDCALL receiveLogMessage(void *, const char *buf, int /*buf_len*/)
	{
		Lock lock(g_mutex); // serialize logging calls from different threads to avoid garbled output.
		Ogre::LogManager::getSingletonPtr()->logMessage(buf);
	}

	void STDCALL receiveHeadPose(void *,smEngineHeadPoseData head_pose, smCameraVideoFrame video_frame)
	{
		Lock lock(g_mutex);

		// Get info including data pointer to original image from camera
		smImageInfo video_frame_image_info;
		THROW_ON_ERROR(smImageGetInfo(video_frame.image_handle, &video_frame_image_info)); // reentrant, so ok


		g_app->setHeadPose(head_pose);

		// video_frame_image_info.plane_addr[*] now point to the image memory planes. 
		// The memory is only valid until the end of this routine unless you call smImageAddRef(video_frame.image_handle).
		// So you can deep copy the image data here, or use smImageAddRef() and just copy the pointer.
		// If you use smImageAddRef() you are responsible for calling smImageDestroy() to avoid a memory leak later.

		// In this callback you will typically want to copy the smEngineFaceData data into your own data-structure.
		// Since the smEngineFaceData contains multiple pod types copying it is not atomic and 
		// a mutex is required to avoid the race-condition with any thread simultaneously 
		// reading from your data-structure.
		// Such a race condition will not crash your code but will create weird noise in the tracking data.
		//Ogre::LogManager::getSingletonPtr()->logMessage("Head pose");
	}

};

#endif